package com.lysh.simple;

import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.Charset;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.util.Iterator;
import java.util.Map;

/**
 * @author liyishan
 * @date 2024/8/6 18:15
 * @apiNote
 */

public class HttpClientUtil {
    private static final Logger log = LoggerFactory.getLogger(HttpClientUtil.class);
    public static final int CONNECT_TIMEOUT = 30000;
    public static final int SO_TIMEOUT = 30000;
    public static final int CONN_MANAGER_TIMEOUT = 20000;
    private static final int REQUEST_TIMEOUT = 40000;
    private static final String ENCODING = "UTF-8";
    public static final String DEFAULT_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36";
    public static final RequestConfig DEFAULT_REQUEST_CONFIG = RequestConfig.custom().setSocketTimeout(30000).setConnectTimeout(30000).setConnectionRequestTimeout(20000).setExpectContinueEnabled(false).build();
    public static CloseableHttpClient client;

    public HttpClientUtil() {
    }

    public static String executePostWithSSL(String url, HttpEntity entity, String contentType, String certPath, String certPass) {
        return executePost(httpClientWithSSL(certPath, certPass), url, entity, contentType, (Map)null);
    }

    public static String executePost(CloseableHttpClient httpClient, String url, HttpEntity entity, String contentType, Map<String, String> headers) {
        return executePost(httpClient, url, entity, contentType, headers, Charset.forName("utf-8"));
    }

    public static String executePost(CloseableHttpClient httpClient, String url, HttpEntity entity, String contentType, Map<String, String> headers, Charset responseCharset) {
        String data = "";
        HttpPost httpPost = new HttpPost();
        CloseableHttpResponse response = null;

        try {
            httpPost.setURI(new URI(url));
            httpPost.setHeader("Content-Type", contentType);
            httpPost.setHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36");
            if (null != headers) {
                headers.entrySet().forEach((e) -> {
                    httpPost.setHeader((String)e.getKey(), (String)e.getValue());
                });
            }

            RequestConfig requestConfig = RequestConfig.copy(DEFAULT_REQUEST_CONFIG).build();
            httpPost.setConfig(requestConfig);
            httpPost.setEntity(entity);

            try {
                response = httpClient.execute(httpPost);
                HttpEntity responseEntity = response.getEntity();
                if (responseEntity != null) {
                    data = EntityUtils.toString(responseEntity, responseCharset);
                }
            } finally {
                if (response != null) {
                    response.close();
                }

            }
        } catch (Exception var25) {
            throw new RuntimeException(var25);
        } finally {
            try {
                httpClient.close();
            } catch (IOException var23) {
                var23.printStackTrace();
            }

        }

        return data;
    }

    public static CloseableHttpClient httpClientWithSSL(String certPath, String certPass) {
        SSLContext sslContext = null;

        try {
            KeyStore clientStore = KeyStore.getInstance("PKCS12");
            clientStore.load(new FileInputStream(certPath), certPass.toCharArray());
            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(clientStore, certPass.toCharArray());
            KeyManager[] kms = kmf.getKeyManagers();
            sslContext = SSLContext.getInstance("TLSv1");
            sslContext.init(kms, (TrustManager[])null, new SecureRandom());
        } catch (Exception var6) {
            throw new RuntimeException(var6);
        }

        HttpClientBuilder builder = HttpClients.custom();
        builder.setSSLContext(sslContext);
        return builder.build();
    }

    public static String doPost(String url, Map<String, String> param) throws IOException {
        return send(RequestBuilder.post(url), param);
    }

    public static String send(RequestBuilder requestBuilder, Map<String, String> paramsMap) throws IOException {
        requestBuilder.setCharset(Charset.forName("UTF-8"));
        String responseText = "";
        if (paramsMap != null) {
            Iterator var3 = paramsMap.entrySet().iterator();

            while(var3.hasNext()) {
                Map.Entry<String, String> param = (Map.Entry)var3.next();
                requestBuilder.addParameter((String)param.getKey(), (String)param.getValue());
            }

            CloseableHttpResponse response = client.execute(requestBuilder.build());
            if (response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    responseText = EntityUtils.toString(entity, "UTF-8");
                }
            }
        }

        return responseText;
    }

    public static String postJson(String url, String param) {
        StringEntity entity = new StringEntity(param, Charset.forName("UTF-8"));
        HttpPost post = new HttpPost(url);
        post.setEntity(entity);
        post.setHeader("Content-type", "application/json");
        String returnStr = "";

        try {
            CloseableHttpResponse response = client.execute(post);
            returnStr = EntityUtils.toString(response.getEntity());
        } catch (IOException var7) {
            log.error("POST 请求失败 url:{},param:{} e:", new Object[]{url, param, var7});
        }

        return returnStr;
    }

    public static String postJson(String url, String param, Map<String, String> addHeaders) {
        StringEntity entity = new StringEntity(param, Charset.forName("UTF-8"));
        HttpPost post = new HttpPost(url);
        post.setEntity(entity);
        post.setHeader("Content-type", "application/json");
        if (!CollectionUtils.isEmpty(addHeaders)) {
            addHeaders.forEach((k, v) -> {
                post.setHeader(k, v);
            });
        }

        String returnStr = "";

        try {
            CloseableHttpResponse response = client.execute(post);
            returnStr = EntityUtils.toString(response.getEntity(), Charset.forName("UTF-8"));
        } catch (IOException var7) {
            log.error("POST 请求失败 url:{},param:{} e:", new Object[]{url, param, var7});
        }

        return returnStr;
    }

    public static String postWithXml(String url, Map<String, String> params) {
        StringEntity entity = new StringEntity(XmlUtils.mapToXml(params), Charset.forName("UTF-8"));
        HttpPost post = new HttpPost(url);
        post.setEntity(entity);
        post.setHeader("Content-type", "text/html");
        String returnStr = "";

        try {
            CloseableHttpResponse response = client.execute(post);
            returnStr = EntityUtils.toString(response.getEntity(), "UTF-8");
        } catch (IOException var7) {
            log.error("POST 请求失败 url:{},param:{} e:", new Object[]{url, params, var7});
        }

        return returnStr;
    }

    public static String getJson(String url, String param) {
        StringEntity entity = new StringEntity(param, ContentType.APPLICATION_JSON);
        HttpEntityEnclosingRequestBase httpEntity = new HttpEntityEnclosingRequestBase() {
            public String getMethod() {
                return "GET";
            }
        };
        httpEntity.setEntity(entity);
        httpEntity.setURI(URI.create(url));
        String returnStr = "";

        try {
            CloseableHttpResponse response = client.execute(httpEntity);
            returnStr = EntityUtils.toString(response.getEntity(), Charset.forName("UTF-8"));
        } catch (IOException var6) {
            log.error("GET 请求失败 url:{},param:{} e:", new Object[]{url, param, var6});
        }

        return returnStr;
    }

    public static String getJson(String url, String param, Map<String, String> addHeaders) {
        StringEntity entity = new StringEntity(param, ContentType.APPLICATION_JSON);
        HttpEntityEnclosingRequestBase httpEntity = new HttpEntityEnclosingRequestBase() {
            public String getMethod() {
                return "GET";
            }
        };
        httpEntity.setEntity(entity);
        httpEntity.setURI(URI.create(url));
        if (!CollectionUtils.isEmpty(addHeaders)) {
            addHeaders.forEach((k, v) -> {
                httpEntity.setHeader(k, v);
            });
        }

        String returnStr = "";

        try {
            CloseableHttpResponse response = client.execute(httpEntity);
            returnStr = EntityUtils.toString(response.getEntity(), Charset.forName("UTF-8"));
        } catch (IOException var7) {
            log.error("GET 请求失败 url:{},param:{} e:", new Object[]{url, param, var7});
        }

        return returnStr;
    }

    public static String putJson(String url, String param, Map<String, String> addHeaders) {
        StringEntity entity = new StringEntity(param, Charset.forName("UTF-8"));
        HttpPut put = new HttpPut(url);
        put.setEntity(entity);
        put.setHeader("Content-type", "application/json");
        if (!CollectionUtils.isEmpty(addHeaders)) {
            addHeaders.forEach((k, v) -> {
                put.setHeader(k, v);
            });
        }

        String returnStr = "";

        try {
            CloseableHttpResponse response = client.execute(put);
            returnStr = EntityUtils.toString(response.getEntity(), Charset.forName("UTF-8"));
        } catch (IOException var7) {
            log.error("PUT 请求失败 url:{},param:{} e:", new Object[]{url, param, var7});
        }

        return returnStr;
    }

    static {
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30000).setConnectionRequestTimeout(40000).setSocketTimeout(30000).build();
        client = HttpClients.custom().setDefaultRequestConfig(requestConfig).setMaxConnTotal(300).setMaxConnPerRoute(150).build();
    }
}
